package com.zenithmind.common.metrics;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 指标服务接口
 * 遵循依赖倒置原则：依赖抽象而非具体实现
 * 遵循接口隔离原则：只包含指标收集和查询相关的操作
 */
public interface MetricsService {
    
    /**
     * 记录计数器指标
     * 
     * @param name 指标名称
     * @param value 计数值
     * @param tags 标签
     */
    void recordCounter(String name, double value, Map<String, String> tags);
    
    /**
     * 记录计数器指标（无标签）
     * 
     * @param name 指标名称
     * @param value 计数值
     */
    void recordCounter(String name, double value);
    
    /**
     * 增加计数器
     * 
     * @param name 指标名称
     * @param tags 标签
     */
    void incrementCounter(String name, Map<String, String> tags);
    
    /**
     * 增加计数器（无标签）
     * 
     * @param name 指标名称
     */
    void incrementCounter(String name);
    
    /**
     * 记录计时器指标
     * 
     * @param name 指标名称
     * @param duration 持续时间（毫秒）
     * @param tags 标签
     */
    void recordTimer(String name, long duration, Map<String, String> tags);
    
    /**
     * 记录计时器指标（无标签）
     * 
     * @param name 指标名称
     * @param duration 持续时间（毫秒）
     */
    void recordTimer(String name, long duration);
    
    /**
     * 记录仪表盘指标
     * 
     * @param name 指标名称
     * @param value 当前值
     * @param tags 标签
     */
    void recordGauge(String name, double value, Map<String, String> tags);
    
    /**
     * 记录仪表盘指标（无标签）
     * 
     * @param name 指标名称
     * @param value 当前值
     */
    void recordGauge(String name, double value);
    
    /**
     * 记录直方图指标
     * 
     * @param name 指标名称
     * @param value 值
     * @param tags 标签
     */
    void recordHistogram(String name, double value, Map<String, String> tags);
    
    /**
     * 记录直方图指标（无标签）
     * 
     * @param name 指标名称
     * @param value 值
     */
    void recordHistogram(String name, double value);
    
    /**
     * 开始计时
     * 
     * @param name 指标名称
     * @return 计时器句柄
     */
    TimerHandle startTimer(String name);
    
    /**
     * 开始计时（带标签）
     * 
     * @param name 指标名称
     * @param tags 标签
     * @return 计时器句柄
     */
    TimerHandle startTimer(String name, Map<String, String> tags);
    
    /**
     * 获取指标值
     * 
     * @param name 指标名称
     * @return 指标值
     */
    MetricValue getMetricValue(String name);
    
    /**
     * 获取指标值（带标签）
     * 
     * @param name 指标名称
     * @param tags 标签
     * @return 指标值
     */
    MetricValue getMetricValue(String name, Map<String, String> tags);
    
    /**
     * 获取所有指标
     * 
     * @return 指标列表
     */
    java.util.List<MetricInfo> getAllMetrics();
    
    /**
     * 清除指标
     * 
     * @param name 指标名称
     */
    void clearMetric(String name);
    
    /**
     * 清除所有指标
     */
    void clearAllMetrics();
    
    /**
     * 计时器句柄
     */
    interface TimerHandle {
        /**
         * 停止计时并记录
         */
        void stop();
        
        /**
         * 获取已经过的时间（毫秒）
         */
        long getElapsedTime();
    }
    
    /**
     * 指标值
     */
    class MetricValue {
        private String name;
        private double value;
        private Map<String, String> tags;
        private LocalDateTime timestamp;
        
        public MetricValue(String name, double value, Map<String, String> tags, LocalDateTime timestamp) {
            this.name = name;
            this.value = value;
            this.tags = tags;
            this.timestamp = timestamp;
        }
        
        // Getters
        public String getName() { return name; }
        public double getValue() { return value; }
        public Map<String, String> getTags() { return tags; }
        public LocalDateTime getTimestamp() { return timestamp; }
    }
    
    /**
     * 指标信息
     */
    class MetricInfo {
        private String name;
        private String type;
        private String description;
        private Map<String, String> tags;
        private LocalDateTime createTime;
        
        public MetricInfo(String name, String type, String description, 
                         Map<String, String> tags, LocalDateTime createTime) {
            this.name = name;
            this.type = type;
            this.description = description;
            this.tags = tags;
            this.createTime = createTime;
        }
        
        // Getters
        public String getName() { return name; }
        public String getType() { return type; }
        public String getDescription() { return description; }
        public Map<String, String> getTags() { return tags; }
        public LocalDateTime getCreateTime() { return createTime; }
    }
}
